package com.toKnow.controller;

import com.google.code.kaptcha.Constants;
import com.toKnow.model.dto.UserRegisterDTO;
import com.toKnow.model.vo.CommonResult;
import com.toKnow.model.vo.UserRegisterVO;
import com.toKnow.model.vo.transfer.UserRegisterVOTransfer;
import com.toKnow.service.RegisterService;
import com.toKnow.utils.JwtActivateUtil;
import com.toKnow.utils.SessionAndCookieUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.UUID;

/**
 * 处理注册相关：包括注册表单检查、发邮件激活用户
 */
@Controller
@RequestMapping(value = "/api/register")
public class RegisterController {

    @Resource
    private RegisterService registerService;

    /**
     * ajax检查用户名是否重复，6-18，只有英文数字下划线。只在输入框旁显示提示文字
     * /register/check/username
     * POST{username:String}{commonResult:CommonResult}
     */
    @RequestMapping(value = "/check/username", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult checkRegisterUsername(String username){
        CommonResult cm = new CommonResult();
        String message = registerService.checkUsername(username);
        cm.setSuccess(message.equals(""));
        cm.setMessage(message);
        return cm;
    }

    /**
     * ajax检查密码是否符合规范，至少包含数字字母和特殊字符。只在输入框旁显示提示文字
     * /register/check/userpwd
     * POST{userpwd:String}{commonResult:CommonResult}
     */
    @RequestMapping(value = "/check/userpwd", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult checkRegisterUserpwd(String userpwd){
        CommonResult cm = new CommonResult();
        String message = registerService.checkUserpwd(userpwd);
        cm.setSuccess(message.equals(""));
        cm.setMessage(message);
        return cm;
    }

    /**
     * ajax检查用户邮箱是否重复，符合规范。只在输入框旁显示提示文字
     * /register/check/email
     * POST{email:String}{commonResult:CommonResult}
     */
    @RequestMapping(value = "/check/email", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult checkRegisterEmail(String email){
        CommonResult cm = new CommonResult();
        String message = registerService.checkEmail(email);
        cm.setSuccess(message.equals(""));
        cm.setMessage(message);
        return cm;
    }

    /**
     * ajax生成验证码图片，并将答案存入session。只在输入框旁显示提示文字
     * /register/generate/code
     * GET{random:Integer[Math.random()]}{图片url，直接放在scr接收即可}
     * 验证码图片样式要在spring.xml文件中修改！
     */
    @RequestMapping(value = "/generate/code")
    @ResponseBody
    public void generateCode(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        registerService.generateCode(request, response);
    }

    /**
     * ajax验证用户输入的验证码。只在输入框旁显示提示文字
     * /register/verify/code
     * POST{userInput:String[用户输入的验证码]}{commonResult:CommonResult}
     */
    @RequestMapping(value = "/verify/code", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult verifyCode(HttpSession session, String user_input) {
        CommonResult cm = new CommonResult();
        cm.setSuccess(false);
        //验证验证码
        String code = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if(code == null){
            cm.setMessage("未生成验证码");
        }else{
            if(code.equalsIgnoreCase(user_input)){
                cm.setSuccess(true);
                cm.setMessage("");
            }else{
                cm.setMessage("请输入正确的验证码");
            }
        }
        return cm;
    }

    /**
     * ajax注册账户，如果注册成功则发送激活邮件。会有弹窗，页面不变。
     * /register/sendmail
     * POST{username:String, userpwd:String, email:String} {commonResult:CommonResult}
     */
    @RequestMapping(value = "/sendmail", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult sendMail(HttpServletRequest request, UserRegisterVO userRegisterVO){
        CommonResult cm = new CommonResult();
        //获取用户注册信息，生成激活码，创建userDTO
        UserRegisterDTO userRegisterDTO = UserRegisterVOTransfer.INSTANCE.toUserEditNormalDTO(userRegisterVO);
        userRegisterDTO.setActivateCode(UUID.randomUUID().toString().replaceAll("-", ""));
        //注册用户
        String message = registerService.registerUser(request, userRegisterDTO);
        //设置返回值
        cm.setSuccess(message.equals(""));
        cm.setMessage(message);
        return cm;
    }

    /**
     * 在邮件中点击链接激活账户。跳转到用户主页（默认免登录，设置cookie）。
     * /register/activate
     * GET{activateToken:String} {commonResult:CommonResult}
     */
    @RequestMapping("/activate")
    public ModelAndView validateMail(HttpServletRequest request, HttpServletResponse response, String activateToken) {
        ModelAndView mv = new ModelAndView();
        CommonResult cm = new CommonResult();
        Integer activateSuccess = 0; // 默认未激活
        String username = null;
        String userpwd = null;
        String email;
        String activateCode;
        if(JwtActivateUtil.verify(activateToken)){ // token有效则进行激活操作
            username = JwtActivateUtil.getInfo(activateToken, "username");
            userpwd = JwtActivateUtil.getInfo(activateToken, "userpwd");
            email = JwtActivateUtil.getInfo(activateToken, "email");
            activateCode = JwtActivateUtil.getInfo(activateToken, "activateCode");
            activateSuccess = registerService.activateUser(username, email, activateCode);
        }
        if(activateSuccess == 1){ //激活成功，设置cookie，直接登录账号
            cm.setSuccess(true);
            cm.setMessage("");
            //设置cookie 10天
            SessionAndCookieUtil.setUserCookie(request, response, username, userpwd, 60 * 60 * 24 * 10);
        }else{ //激活失败
            cm.setSuccess(false);
            cm.setMessage("激活失败，可能是因为用户已被激活，或者激活码过期，或者用户名/邮箱已存在于已激活的用户");
        }
        mv.addObject("commonResult", cm);
        mv.setViewName("redirect:/"); //进入首页
        return mv;
    }
}